# -*- coding: UTF-8 -*-
"""
Course:        CS408 Computer Science Project B, TEAM 1
Semester:      2010 SPRING
Project:       DOHN(Web-based Account Book System)

File:          dohn.py
Description:   Main hub for calling other. It is used for making fine URL.
Class:         None

Author:        SungHyuk Im

Comment:       Methods are divided by windows which are described in UI Doc.
               Method name here is used as URL.
               ex) http://(...)/dohn.py/index --> def index
               ex) http://(...)/dohn.py/signup --> def signup
"""


import sessions
import db
import utils
import views
import shortcuts
import transactions
import reports
import users
import mobiles
import datetime


def __check__(req):
    """
    @author: SungHyuk Im
    @summary: Check whether signed in or not. If not, redirects to index.
    """
    if sessions.check_signed(req):
        return True
    else:
        #mod_python.util.redirect(req, utils.get_url(req, 'index')+"?option=3")
        utils.redirect(req, utils.get_url(req, 'index')+"?option=3", specify = True)

def __check_pw__(pw):
    """
    @author: Kyeonghwan Jin
    """
    if not utils.check_password(pw):
        return False
        #redirect
    return True    
#----- Main page

def index(req, option = 0):
    """
    @author: SungHyuk Im
    @summary: Index Page caller.
    @param req: request 
    @return: Transaction List Page(signed in), Login Page(not signed in)
    
    @attention: If URL is just 'dohn.py' then it redirects to 'dohn.py/index'
        because of consistency.
    """
    
    # Test code for req.notes
    """
    if req.prev == None:
        req.notes["option"] = "1"
#        req.internal_redirect("/test/dohn.py/index")
        req.internal_redirect(utils.get_url(req, "index"))
    elif req.prev.notes["option"] == "1":
        req.notes["option"] = "2"
#        req.internal_redirect("/test/dohn.py/index")
        req.internal_redirect(utils.get_url(req, "index"))
    elif req.prev.notes["option"] == "2":
        return 'now 2'
    """
    
#    if not req.prev == None:
#        if 2 == req.prev.notes["option"]:
#            return "option here"
#            req.write(get_html_with_msg("main.html", \
#                                        "Signup success.\\nPlease login."))
#            return utils.get_html_with_msg("main.html", \
#                                           "Signup success.\\n Please login.")
    if 1 == option:    # login error
        #return utils.get_main_with_msg(req, "Login Error!\\nCheck ID or Password.")
        return utils.get_html_with_msg( "main.html", 
                                        "Login Error! Check ID or Password.")
    elif 2 == option:  # signup complete
        #return utils.get_main_with_msg(req, "Signup success.\\nPlease login.")
        return utils.get_html_with_msg("main.html",
                                       "Signup success. Please login.")
    elif 3 == option:  # not authorized
        return utils.get_html_with_msg("main.html",
                                       "You are not authorized. Login please.")
    
    # [ALREADY SIGNED IN] then, redirect to transaction
    if sessions.check_signed(req):
        #mod_python.util.redirect(req, utils.get_url(req, 'transaction'))
        utils.redirect(req, 'transaction')
    
    # [NOT SIGNED IN YET] 
    # If '.../dohn.py/index' -> just go
    # Else                   -> redirect to /index    
    
    if 'index' in req.uri:
        views_obj = views.View()
        return views_obj.show_index_window(req)
    else:
        # v1
        #req.internal_redirect(req_uri + "/index")
        
        # v2: check '/' because of dohn.py//index
        #if req_uri[-1] == "/":
        #    adding = "index"
        #else:
        #    adding = "/index"
        
        # v3: improve v2
        #adding = req.uri[-1] == "/" and "index" or "/index"
        #mod_python.util.redirect(req, req.uri + adding)
        
        # v4
        #mod_python.util.redirect(req, utils.get_url(req, 'index'))
        
        # v5
        utils.redirect(req, 'index')
    return

def sign_in(req, user_id, password):
    """
    @author: SungHyuk Im
    @summary: Sign in action handler.
    @param req: request
    @param user_id: user id from POST
    @param password: password from POST
    @return: Transaction List Page(login success)
        Index page with error(login fail)
    """
    if sessions.sign_in(req, user_id, password) == True and not len(user_id) == 0:
        # req.uri: /test/dohn.py/sign_in
        # Get last login time
        query = "SELECT last_login FROM member_tb WHERE user_id='%s'" % user_id
        data = db.run_query(query)
        
        # if last login time was last month, update count of shortcut
        if data[0][0] != None:
            if data[0][0].month < datetime.date.today().month:
                query = "SELECT num, plan_total FROM shortcut_tb WHERE user_id='%s'" % user_id
                old = db.run_query(query)
                in_query = []
                for aitem in old:
                    in_query.append("UPDATE shortcut_tb SET plan_remain='%d' WHERE num='%d';" % (int(aitem[1]),int(aitem[0])))
                db.execute_querys(in_query)
        
        # Record last login time
        query = "UPDATE member_tb SET last_login = '%s' WHERE(user_id = '%s')" \
                %(utils.get_current_time(), user_id)
        db.execute_query(query)
        #db.execute_query("SET NAMES utf8")
        # Redirect to transaction list page
        utils.redirect(req, 'transaction')
    else:
        # Redirect to index with login error message
        return index(req, 1)
    return

def sign_up(req):
    """
    @author: SungHyuk Im
    @summary: Sign Up Page caller.
    @param req: request 
    @return: Sign Up Page
    """
    users_obj = users.SignupView()
    return users_obj.show_signup_window()

def sign_out(req):
    """
    @author: SungHyuk Im
    @summary: Sing out action handler / after sign out redirect to index
    """
    # v1: for test
    # In parenthesis, left one is run first.
    #src = "ID: %s / Sign out: %s" % (sessions.get_id(req), sessions.sign_out(req))
    #return src

    # v2: sign out, then redirect to index page
    sessions.sign_out(req)
    #mod_python.util.redirect(req, utils.get_url(req,'index'))
    utils.redirect(req, 'index')
    pass

def check_id(req, id):
    """
    @author: SungHyuk Im
    @summary: Check id page caller.
    @param req: request 
    @precondition: This is called during sign up.
    @return: Check id page
    """
    users_obj = users.SignupView()
    return users_obj.show_id_check_window(req, id)

def do_signup(req, user_id, email, pw1, pw2):
    """
    @author: SungHyuk Im
    @summary: Sign up action handler
    
    @see: Where should checking be placed? HTML or python?
    @todo: it should check data validation like following.
            1. pw1 and pw2 are same?
            2. email is valid?
            3. user_id is enough long?
            4. every input has unavailable character?
    """
    #sessions.sign_out(req)
    users_obj = users.SignupController()
    success = users_obj.query_add_userinfo(user_id, email, pw1, pw2)
    
    # v1
#    utils.redirect(req, 'index')

    # v2
    if success == True:
        return index(req, 2)
    else:
        src = """<script> alert("ID is not available. Check ID again."); location.replace("sign_up"); </script>"""
        return src
    
    # v3: req.notes
#    req.notes["option"] = "2"
#    req.internal_redirect(utils.get_url(req,'index'))
#    return


#------------------------------
#----- Transaction

def transaction(req):
    """
    @author: SungHyuk Im
    @summary: Transaction Index Page caller
    @param req: request 
    @return: Transaction Index page
    
    @see:
    To-do 1: take 2 date values by get method to print transaction list
    """
    __check__(req)
    trx_obj = transactions.TransactionView()
    return trx_obj.show_index_window(req)

def transaction_list(req):
    """
    @author: SungHyuk Im
    @summary: Transaction List Page caller
    @return: Transaction List Page
    """
    __check__(req)
    trx_obj = transactions.TransactionView()
    return trx_obj.show_list_window(req)

def transaction_date(req, date1, date2):
    """
    @author: SungHyuk Im
    @summary: Transaction search by date page caller
    """
    __check__(req)
    #date1 = "%4s-%2s-%2s" % (year1, month1, day1)
    #date2 = "%4s-%2s-%2s" % (year2, month2, day2)
    trx_obj = transactions.TransactionView()
    return trx_obj.show_list_window(req, date1, date2)

def transaction_keyword(req, input_word):
    """
    @author: SungHyuk Im
    @summary: Transaction search by keyword page caller
    """
    __check__(req)
    trx_obj = transactions.TransactionView()
    return trx_obj.show_list_window(req, 0, 0, input_word)

def transaction_add(req):
    """
    @author: SungHyuk Im
    @summary: Transaction Add Page caller
    @return: Transaction Add Page
    """
    __check__(req)
    trx_obj = transactions.TransactionView()
    return trx_obj.show_add_window(req)

def transaction_edit(req, num):
    """
    @author: SungHyuk Im
    @summary: Transaction Edit Page caller
    @param num: Transaction index
    @return: Transaction Edit Page
    @attention: : Parameter num is required.
    """
    __check__(req)
    trx_obj = transactions.TransactionView()
    return trx_obj.show_edit_window(req, num)

def import_file(req):
    """
    @author: SungHyuk Im
    @summary: Import File Page caller
    @return: Import File Page
    """
    __check__(req)
    trx_obj = transactions.TransactionView()
    return trx_obj.show_import_window(req)

def import_suggest(req):
    """
    @author: SungHyuk Im
    @summary: Import Suggestion Page caller
    @return: Import Suggestion Page
    """
    __check__(req)
    trx_obj = transactions.TransactionView()
    return trx_obj.show_suggest_window()

def do_transaction_add(req, date, description, amount, category):
    """
    @author: SungHyuk Im
    @summary: Transaction Add Action handler
    """
    __check__(req)
    trx_obj = transactions.TransactionController()
    return trx_obj.query_add_transaction(req, date, description, amount, category)
    #return 'add complete'

def do_transaction_edit(req, num, date, description, amount, category):
    """
    @author: SungHyuk Im
    @summary: Transaction Edit Action handler
    """
    # return num, date, description, amount, category
    __check__(req)
    trx_obj = transactions.TransactionController()
    return trx_obj.query_edit_transaction(req, num, date, description, 
                                          amount, category)

def do_transaction_delete(req, num):
    """
    @author: SungHyuk Im
    @summary: Transaction Delete Action handler
    @param num: Transaction index, column name: num
    """
    __check__(req)
    trx_obj = transactions.TransactionController()
    trx_obj.query_delete_transaction(req, num)
    utils.redirect(req, 'index')
    return

def do_import_file(req):
    """
    @author: SungHyuk Im
    """
    __check__(req)
    try:
        fptr = req.form['fileupload'].file
    except:
        src_path = utils.get_abs_path() + "/html/import_error.html"
        src = utils.get_file_content(src_path)
        return src
    
    temp_name = utils.save_to_tempfile(fptr)
    fptr.close()
    trx_obj = transactions.TransactionView()
    return trx_obj.show_suggest_window(req, temp_name)

def do_suggestion_add(req, date, description, amount, category, deleted):
    """
    @author: SungHyuk Im
    """
    #return "date", date, "desc", description, "amnt", amount, "cate", category, "del", deleted
    
    number = len(date)
    for i in range(number):
        #description[i] = description[i].decode('utf-8').encode('euc-kr')
        
        #if deleted[i] != "Del":
        #    do_transaction_add(req, date[i], description[i], amount[i], category[i])
        if not str(i) in deleted:
            do_transaction_add(req, date[i], description[i], amount[i], category[i])
        
    return "date", date, "desc", description, "amnt", amount, "cate", category, "del", deleted
    #return


#------------------------------
#----- Shortcut

def shortcut(req):
    """
    @author: SungHyuk Im
    @summary: Shortcut Index Page caller
    @return: Shortcut Index Page
    """
    __check__(req)
    scut_obj = shortcuts.ShortcutView()
    return scut_obj.show_index_window(req)

def shortcut_list(req):
    """
    @author: SungHyuk Im
    @summary: Shortcut List Page caller
    @return: Shortcut List Page
    """
    __check__(req)
    scut_obj = shortcuts.ShortcutView()
    return scut_obj.show_list_window(req)

def shortcut_add(req):
    """
    @author: SungHyuk Im
    @summary: Shortcut Add Page caller
    @return: Shortcut Add Page
    """
    __check__(req)
    scut_obj = shortcuts.ShortcutView()
    return scut_obj.show_add_window(req)

def shortcut_edit(req, num):
    """
    @author: SungHyuk Im
    @summary: Shortcut Edit Page caller
    @return: Shortcut Edit Page
    """
    __check__(req)
    scut_obj = shortcuts.ShortcutView()
    return scut_obj.show_edit_window(req, num)

def do_shortcut_add(req, category, description, amount, plan_total):
    """
    @author: Kyeonghwan Jin
    """
    __check__(req)
    trx_obj = shortcuts.ShortcutController()
    return trx_obj.query_add_shortcut(req, description, amount, category, plan_total, plan_total)
    #return 'add complete'

def do_shortcut_edit(req, num, description, amount, category, plan_remain, plan_total):
    """
    @author: Kyeonghwan Jin
    """
    __check__(req)
    trx_obj = shortcuts.ShortcutController()
    return trx_obj.query_edit_shortcut(req, num, description, amount, category, plan_remain, plan_total)

def do_shortcut_delete(req, num):
    """
    @author: Kyeonghwan Jin
    """
    __check__(req)
    trx_obj = shortcuts.ShortcutController()
    trx_obj.query_delete_shortcut(req, num)
    utils.redirect(req, 'shortcut')
    return


#------------------------------
#----- Report

def report(req):
    """
    @author: SungHyuk Im
    @summary: Report Index Page caller
    @return: Report Index Page
    """
    __check__(req)
    rep_obj = reports.ReportView()
    return rep_obj.show_index_window(req)

def periodical_report(req,period1 = utils.get_current_month(),period2 = utils.get_current_month()):
    """
    @author: SungHyuk Im
    @summary: Periodical Report Page caller
    @return: Periodical Report Page
    """
    __check__(req)
    rep_obj = reports.ReportView()
    return rep_obj.show_periodical_window(req,period1,period2)

def categorical_report(req,period1 = utils.get_current_month(),period2 = utils.get_current_month()):
    """
    @author: SungHyuk Im
    @summary: Categorical Report Page caller
    @return: Categorical Report Page
    """
    __check__(req)
    rep_obj = reports.ReportView()
    return rep_obj.show_categorical_window(req,period1,period2)


#------------------------------
#----- My page

def mypage(req):
    """
    @author: SungHyuk Im
    @summary: Mypage Index Page caller
    @return: Mypage Index Page
    """
    __check__(req)
    users_obj = users.MypageView()
    return users_obj.show_index_window(req)

def user_info(req):
    """
    @author: SungHyuk Im
    @summary: Userinfo Page caller
    @return: Userinfo Page
    """
    __check__(req)
    users_obj = users.MypageView()
    return users_obj.show_userinfo_window(req)

def do_user_info_edit(req, EMAIL, PW1, PW2):
    """
    @author: Kyeonghwan Jin
    """
    __check__(req)
    
    if not PW1 == PW2:
        #passwords are not equal
        return "PASSWORDS NOT CONFIRMED"
    
    #will be erased after implementing error message dialogs
    if not __check_pw__(PW1):
        return "TOO SHORT"
    
    __check_pw__(PW1)
    
    users_obj = users.SignupController()
    users_obj.query_edit_userinfo(req, EMAIL, PW1)
    
    utils.redirect(req, 'mypage')
    
def user_out(req):
    """
    @author: Sangyong Gil
    @param req: Request
    @summary: Membership termination confirm page caller
    @return: Membership termination confirm page
    """
    __check__(req)
    users_obj = users.MypageView()
    return users_obj.show_user_out_window(req)

def do_user_out(req, PW1):
    """
    @author: Sangyong Gil
    @param req: Request
    @param pw: Password for confirmation
    @summary: If password is correct, cancel the account.
    """
    __check__(req)
    users_obj = users.MypageController()
    return users_obj.query_delete_userinfo(req, PW1)
    
def category_list(req):
    """
    @author: SungHyuk Im
    @summary: Category Management Page caller
    @return: Category Management Page
    """
    __check__(req)
    users_obj = users.MypageView()
    return users_obj.show_category_window(req)

def category_add(req):
    """
    @author: Kyeonghwan Jin
    """
    users_obj = users.MypageView()
    return users_obj.show_category_add_window()

def do_category_add(req, category_name):
    """
    @author: Kyeonghwan Jin
    """
    __check__(req)
    mp_obj = users.MypageController()
    return mp_obj.query_add_category(req, category_name)
    #return 'add complete'

def do_category_delete(req, num):
    """
    @author: Kyeonghwan Jin
    """
    __check__(req)
    mp_obj = users.MypageController()
    mp_obj.query_delete_category(req, num)
    utils.redirect(req, 'category_list')
    return

def pattern_list(req):
    """
    @author: SungHyuk Im
    @summary: Pattern Management Page caller
    @return: Pattern Management Page
    """
    __check__(req)
    users_obj = users.MypageView()
    return users_obj.show_pattern_window(req)

def pattern_add(req, cat):
    """
    @author: SungHyuk Im
    @summary: Pattern Management Page caller
    @return: Pattern Management Page
    """
    users_obj = users.MypageView()
    return users_obj.show_pattern_add_window(req, cat)

def do_pattern_add(req, category, description_name):
    __check__(req)
    users_obj = users.MypageController()
    users_obj.query_add_pattern(req, category, description_name)
    return

def do_pattern_delete(req, pattern):
    __check__(req)
    users_obj = users.MypageController()
    users_obj.query_delete_pattern(req, pattern)
    return

def admin(req):
    """
    @author: SungHyuk Im
    @summary: Member Management Page for Administrator caller
    @return: Member Management Page for Administrator
    """
    __check__(req)
    admin_obj = users.AdminView()
    return admin_obj.show_index_window(req)

def confirm_user_delete(req, user):
    __check__(req)
    admin_obj = users.AdminView()
    return admin_obj.show_user_delete_window(req, user)

def do_user_delete(req, user):
    __check__(req)
    admin_obj = users.AdminController()
    admin_obj.query_delete_user(req, user)
    return


#------------------------------
#----- Mobile page

def mobile(req):
    """
    @author: SungHyuk Im
    @summary: Mobile Index Page caller
    @return: Mobile Index Page
    """
    mobile_obj = mobiles.MobileView()
    return mobile_obj.show_index_window(req)


def mobile_sign_in(req, user_id = None, password = None):
    """
    @author: Gangmin Park
    @summary: Sign in action handler.
    @param req: request
    @param user_id: user id from POST
    @param password: password from POST
    @return: Show shortcut list page(login success)
             mobile sing-in window(login fail)
    """
    if user_id == None or password == None:
        utils.redirect(req, 'mobile')
    
    if sessions.sign_in(req, user_id, password) == True:
        query = "UPDATE member_tb SET last_login = '%s' WHERE(user_id = '%s')" \
                %(utils.get_current_time(), user_id)
        db.execute_query(query)
        db.execute_query("SET NAMES utf8")
        utils.redirect(req, 'mobile_list')
    else:
        mobile_obj = mobiles.MobileView()
        return mobile_obj.show_index_window(req)

def mobile_list(req):
    """
    @author: Gangmin Park
    @summary: Mobile List Page caller
    @return: Show shortcut list page(Session is registered)
             mobile sing-in window(Session is not registered)
    """
    if sessions.check_signed(req):
        mobile_obj = mobiles.MobileView()
        return mobile_obj.show_list_window(req)
    else:
        mobile_obj = mobiles.MobileView()
        return mobile_obj.show_signin_window(req)

def mobile_add(req, description):
    """
    @author: Gangmin Park
    @summary: Mobile Add Page caller
    @param description: the transaction description of shorcut 
    @return: Show mobile shortcut add page
    """
    mobile_obj = mobiles.MobileView()
    return mobile_obj.show_add_window(req, description)

def on_click_confirm(req, button):
    """
    @author: Gangmin Park
    @summary: Confirm Controller Caller
    @param button: the transaction description of shorcut from POST(if user confirm adding)
                   'cancel' from POST(if user concel adding)
    @return: Confirm controller(if user confirm adding)
             Cancle controller(if user cancel adding)
    """
    if button == "cancel":
        mobile_obj = mobiles.MobileController()
        return mobile_obj.on_click_cancel(req)
    else:
        mobile_obj = mobiles.MobileController()
        return mobile_obj.on_click_confirm(req, button)


#------------------------------
#----- FOR TEST

def get_id(req):
    """
    @author: SungHyuk Im
    @summary: Return current signed id.
    """
    return sessions.get_id(req)

